package com.caiden_micheal.base.interceptor;

import com.alibaba.fastjson2.JSON;
import com.caiden_micheal.base.constant.LoggerHead;
import com.caiden_micheal.base.domain.AjxResult;
import com.caiden_micheal.base.utils.BaseContext;
import com.caiden_micheal.base.utils.JwtUtil;
import com.caiden_micheal.base.utils.RedisUtil;
import io.jsonwebtoken.Claims;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Objects;

public class TokenInterceptor implements HandlerInterceptor {
    private final Logger logger = LoggerFactory.getLogger(TokenInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String token = request.getHeader("Authorization");
        Claims claims = JwtUtil.validateUserToken(token);
        if (claims == null) {
            returnJson(response, "Identity verification failed. Token: " + token);
            /*try {
                response.sendRedirect(JwtUtil.jwtProperties.getRedirect());
            } catch (IOException e) {
                logger.error(LoggerHead.errorHead() + "RedirectError: " + e.getMessage());
            }*/
            return false;
        }
        // 验证用户是否登录状态
        String onlineStatusKey = "caiden_micheal:user:" + claims.get("userId") + ":onlineStatus";
        String onlineStatus = RedisUtil.getValue(onlineStatusKey);
        if (StringUtils.isEmpty(onlineStatus)) {
            returnJson(response, "This token has expired, please login again: " + token);
            return false;
        } else if (!Objects.equals(onlineStatus, claims.get("flag"))) {
            returnJson(response, "Token is used maliciously, and the current behavior has been recorded: " + token);
            return false;
        }
        BaseContext.setInfo(claims);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        BaseContext.removenfo();
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }

    private void returnJson(HttpServletResponse response, String message) {
        PrintWriter writer = null;
        response.setContentType("application/json;charset=UTF-8");
        try {
            writer = response.getWriter();
            writer.print(JSON.toJSONString(AjxResult.jwtError(message)));
        } catch (IOException e) {
            logger.error(LoggerHead.errorHead() + "Token IO读写错误: " + e.getMessage());
        } finally {
            if (writer != null) writer.close();
        }
    }
}